﻿Option Explicit On

Imports System
Imports System.Text
Imports System.IO
Imports System.IO.Compression
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Data
Imports System.Drawing
Imports System.Windows.Forms
Imports System.Diagnostics
Imports System.Drawing.Drawing2D
Imports System.Xml
Imports System.Runtime.InteropServices
Imports System.Collections
Imports System.Object
Imports System.Security.Cryptography
Imports System.Security.Cryptography.Xml
Imports System.Security.Cryptography.X509Certificates

Public Class clsFerramentas

    Public Class File
        ''' <summary>
        ''' Grava conteudo dentro de arquivo
        ''' </summary>
        ''' <param name="FilePath">Caminho completo do aquivo</param>
        ''' <param name="Value">Conteúdo a ser gravado</param>
        ''' <remarks></remarks>
        Public Sub FileSave(ByRef FilePath As String, ByRef Value As String)
            Dim FileWrite As New IO.StreamWriter(FilePath)
            FileWrite.Write(Value)
            FileWrite.Flush()
            FileWrite.Close()
        End Sub
        ''' <summary>
        ''' Retorna o conteúdo do arquivo
        ''' </summary>
        ''' <param name="FilePath">Caminho completo do arquivo</param>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Function FileRead(ByRef FilePath As String) As String
            Dim FileToRead As New IO.StreamReader(FilePath, System.Text.Encoding.Default)
            Dim inputText As String = FileToRead.ReadToEnd
            Return inputText
        End Function
        ''' <summary>
        ''' Retorna o nome do arquivo 
        ''' </summary>
        ''' <param name="FilePath">Caminho completo do arquivo</param>
        ''' <param name="blnExtension">Retorna com a extensão do arquivo</param>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Function FileName(ByRef FilePath As String, Optional ByRef blnExtension As Boolean = True) As String
            Dim strOut As String = ""
            Dim mtzFile() As String = FilePath.Split("\")

            If mtzFile.Length > 0 Then
                strOut = mtzFile(mtzFile.Length - 1)
                If blnExtension = False Then
                    If InStr(strOut, ".") > 0 Then
                        strOut = Left(strOut, InStr(strOut, ".") - 1)
                    End If
                End If
            End If
            FileName = strOut
        End Function
    End Class

    Public Class Base64Code
        ''' <summary>
        ''' Codifica e Decodifica imagens em Base64
        ''' </summary>
        ''' <remarks></remarks>
        Public Class Imagens
            ''' <summary>
            ''' Converte imagem em string Base64
            ''' </summary>
            ''' <param name="image">Imagem a ser convertida</param>
            ''' <param name="format">Formato da imagem System.Drawing.Imaging.ImageFormat</param>
            ''' <returns></returns>
            ''' <remarks></remarks>
            Public Shared Function ImageToBase64(ByVal image As Image, ByVal format As System.Drawing.Imaging.ImageFormat) As String
                Dim ms As New MemoryStream()
                ' Convert Image to byte[]
                image.Save(ms, format)
                Dim imageBytes As Byte() = ms.ToArray()

                ' Convert byte[] to Base64 String
                Dim base64String As String = Convert.ToBase64String(imageBytes)
                Return base64String
            End Function
            ''' <summary>
            ''' Converte Base64 em uma imagem
            ''' </summary>
            ''' <param name="base64String">String Base64 a ser convertida</param>
            ''' <returns></returns>
            ''' <remarks></remarks>
            Public Shared Function Base64ToImage(ByVal base64String As String) As Image
                ' Convert Base64 String to byte[]
                Dim imageBytes As Byte() = Convert.FromBase64String(base64String)
                Dim ms As New MemoryStream(imageBytes, 0, imageBytes.Length)

                ' Convert byte[] to Image
                ms.Write(imageBytes, 0, imageBytes.Length)
                Dim image__1 As Image = Image.FromStream(ms, True)
                Return image__1
            End Function
        End Class

        Public Class Strings
            Public Shared Sub Teste()
                '-- TESTE
                Dim FileRead As New IO.StreamReader("FilePath")
                Dim inputText As String = FileRead.ReadToEnd
                Debug.WriteLine("Input text: {0}", inputText)

                Dim bytesToEncode As Byte()
                bytesToEncode = System.Text.Encoding.ASCII.GetBytes(inputText)

                Dim encodedText As String
                encodedText = Convert.ToBase64String(bytesToEncode)
                Debug.WriteLine("Encoded text: {0}", encodedText)

                Dim decodedBytes As Byte()
                decodedBytes = Convert.FromBase64String(encodedText)

                Dim decodedText As String
                decodedText = System.Text.Encoding.ASCII.GetString(decodedBytes)
                Debug.WriteLine("Decoded text: {0}", decodedText)

                Dim FileToWrite As New IO.StreamWriter(My.Application.Info.DirectoryPath & "\temp\prod_temp2.jpg")
                FileToWrite.WriteLine(decodedText)
                FileToWrite.Close()
            End Sub

            Public Shared Function FileToBase64(ByVal FilePath As String) As String
                Try
                    If IO.File.Exists(FilePath) Then
                        Dim objByte As Byte() = IO.File.ReadAllBytes(FilePath)
                        Dim arquivo As String = Convert.ToBase64String(objByte)

                        Return arquivo
                    Else
                        Return ""
                    End If
                Catch ex As Exception
                    Return "" & ex.Message
                End Try
            End Function

            Public Shared Function Base64ToString(ByVal Base64 As String) As String
                Try
                    If Base64.Trim <> String.Empty Then
                        Dim decodedBytes As Byte() = Convert.FromBase64String(Base64)
                        Dim decodedText As String = System.Text.Encoding.ASCII.GetString(decodedBytes)
                        Return decodedText
                    Else
                        Return ""
                    End If
                Catch ex As Exception
                    Return "" & ex.Message
                End Try
            End Function

            Public Shared Sub Base64ToFile(ByVal Base64 As String, ByVal FilePath As String)
                Try
                    If Base64.Trim <> String.Empty Then
                        Dim objByte As Byte() = Convert.FromBase64String(Base64)
                        IO.File.WriteAllBytes(FilePath, objByte)
                    Else
                        Throw New Exception("String do tipo Base64 retornou uma string vazia para o arquivo.")
                    End If
                Catch ex As Exception
                    Throw New Exception(ex.Message)
                End Try
            End Sub
        End Class
    End Class

    Public Class HMergedCell
        Inherits DataGridViewTextBoxCell
        Private m_nLeftColumn As Integer = 0
        Private m_nRightColumn As Integer = 0

        ''' <summary>
        ''' Column Index of the left-most cell to be merged.
        ''' This cell controls the merged text.
        ''' </summary>
        Public Property LeftColumn() As Integer
            Get
                Return m_nLeftColumn
            End Get
            Set(ByVal value As Integer)
                m_nLeftColumn = value
            End Set
        End Property

        ''' <summary>
        ''' Column Index of the right-most cell to be merged
        ''' </summary>
        Public Property RightColumn() As Integer
            Get
                Return m_nRightColumn
            End Get
            Set(ByVal value As Integer)
                m_nRightColumn = value
            End Set
        End Property

        Protected Overrides Sub Paint(ByVal graphics As Graphics, _
                                      ByVal clipBounds As Rectangle, _
                                      ByVal cellBounds As Rectangle, _
                                      ByVal rowIndex As Integer, _
                                      ByVal cellState As DataGridViewElementStates, _
                                      ByVal value As Object, _
                                      ByVal formattedValue As Object, _
                                      ByVal errorText As String, _
                                      ByVal cellStyle As DataGridViewCellStyle, _
                                      ByVal advancedBorderStyle As DataGridViewAdvancedBorderStyle, _
                                      ByVal paintParts As DataGridViewPaintParts)
            Try
                Dim mergeindex As Integer = ColumnIndex - m_nLeftColumn
                Dim i As Integer
                Dim nWidth As Integer
                Dim nWidthLeft As Integer
                Dim strText As String

                Dim pen As New Pen(Brushes.Black)

                ' Draw the background
                graphics.FillRectangle(New SolidBrush(SystemColors.Control), cellBounds)

                ' Draw the separator for rows
                graphics.DrawLine(New Pen(New SolidBrush(SystemColors.ControlDark)), cellBounds.Left, cellBounds.Bottom - 1, cellBounds.Right, cellBounds.Bottom - 1)

                ' Draw the right vertical line for the cell
                If ColumnIndex = m_nRightColumn Then
                    graphics.DrawLine(New Pen(New SolidBrush(SystemColors.ControlDark)), cellBounds.Right - 1, cellBounds.Top, cellBounds.Right - 1, cellBounds.Bottom)
                End If

                ' Draw the text
                Dim rectDest As RectangleF = RectangleF.Empty
                Dim sf As New StringFormat()
                sf.Alignment = StringAlignment.Center
                sf.LineAlignment = StringAlignment.Center
                sf.Trimming = StringTrimming.EllipsisCharacter

                ' Determine the total width of the merged cell
                nWidth = 0
                For i = m_nLeftColumn To m_nRightColumn
                    nWidth += Me.OwningRow.Cells(i).Size.Width
                Next

                ' Determine the width before the current cell.
                nWidthLeft = 0
                For i = m_nLeftColumn To ColumnIndex - 1
                    nWidthLeft += Me.OwningRow.Cells(i).Size.Width
                Next

                ' Retrieve the text to be displayed
                strText = Me.OwningRow.Cells(m_nLeftColumn).Value.ToString()

                rectDest = New RectangleF(cellBounds.Left - nWidthLeft, cellBounds.Top, nWidth, cellBounds.Height)
                graphics.DrawString(strText, New Font("Arial", 10, FontStyle.Regular), Brushes.Black, rectDest, sf)
            Catch ex As Exception
                Trace.WriteLine(ex.ToString())
            End Try
        End Sub

    End Class

    Public Class XML
        Public Class Export
            Private Shared myXMLOut As New angXML
            Private Shared myXMLIn As New XmlDocument
            Private Shared FormName_ As Control
            Private Shared FileName_ As String
            Private Shared EnabledState_ As Boolean
            Private Shared strRootXML As String = "/Controles"
            ''' <summary>
            ''' Nome do formulário ou conteiner
            ''' </summary>
            ''' <value></value>
            ''' <remarks></remarks>
            Public Shared WriteOnly Property FormName() As Control
                Set(ByVal value As Control)
                    FormName_ = value
                End Set
            End Property
            ''' <summary>
            ''' Nome do arquivo XML a ser salvo
            ''' </summary>
            ''' <value></value>
            ''' <remarks></remarks>
            Public Shared WriteOnly Property FileName() As String
                Set(ByVal value As String)
                    FileName_ = value
                End Set
            End Property
            ''' <summary>
            ''' Determina se deve ou não ativar/desativar controle de acordo com o controle origem
            ''' </summary>
            ''' <value></value>
            ''' <remarks></remarks>
            Public Shared WriteOnly Property EnabledState() As Boolean
                Set(ByVal value As Boolean)
                    EnabledState_ = value
                End Set
            End Property
            ''' <summary>
            ''' Salva os dados no XML na memória
            ''' </summary>
            ''' <remarks></remarks>
            Public Shared Sub ToMemory()
                Try
                    Dim strMyXML As String = ""
                    With myXMLOut
                        .Create()
                        .Encoding = "ISO-8859-1"
                        .Version = "1.0"
                        .UseCDATA = True

                        .Add.Group(strRootXML)
                        Call GetControls(FormName_)

                        strMyXML = .XML
                    End With

                    Clipboard.Clear()
                    Clipboard.SetText(strMyXML, TextDataFormat.Text)

                Catch ex As Exception
                    Call SendError(ex.Message, ex.StackTrace)
                End Try
            End Sub
            ''' <summary>
            ''' Preenche com os dados XML da memória
            ''' </summary>
            ''' <remarks></remarks>
            Public Shared Sub FromMemory()
                Try
                    Dim strMyXML As String = Clipboard.GetText(TextDataFormat.Text)
                    Dim intControls As Int16
                    Dim strCtlNome As String, strCtlValor As String, blnCtlEnabled As Boolean

                    With myXMLIn
                        .LoadXml(strMyXML)
                        For intControls = 0 To .SelectNodes("/Controles/object").Count - 1
                            strCtlNome = .SelectNodes("/Controles/object/@nome").Item(intControls).InnerText
                            blnCtlEnabled = IIf(.SelectNodes("/Controles/object/@enabled").Item(intControls).InnerText = "True", True, False)
                            strCtlValor = .SelectNodes("/Controles/object/valor").Item(intControls).InnerText
                            '--
                            Call SetControl(FormName_, strCtlNome, blnCtlEnabled, strCtlValor)
                        Next
                    End With
                Catch ex As Exception
                    Call SendError(ex.Message, ex.StackTrace)
                End Try
            End Sub

            Private Shared Sub GetControls(ByVal controlP As Control)
                Dim strMyName As String = ""
                Try
                    Dim ctl As Control
                    Dim strXPath As String = strRootXML & "/object"
                    With myXMLOut
                        For Each ctl In controlP.Controls
                            strMyName = ctl.Name
                            If TypeOf ctl Is Label Then
                                If strMyName Like "lbl*" Then
                                    .Add.Group(strXPath)
                                    .Add.Att(strXPath & "/tipo", "label")
                                    .Add.Att(strXPath & "/nome", ctl.Name)
                                    .Add.Att(strXPath & "/enabled", ctl.Enabled.ToString)
                                    .Add.Tag(strXPath & "/valor", ctl.Text)
                                End If
                            ElseIf TypeOf ctl Is RichTextBox Then
                                DirectCast(ctl, RichTextBox).Text = String.Empty
                            ElseIf TypeOf ctl Is AnguloTextBox Then
                                .Add.Group(strXPath)
                                .Add.Att(strXPath & "/tipo", "AnguloTextBox")
                                .Add.Att(strXPath & "/nome", ctl.Name)
                                .Add.Att(strXPath & "/enabled", ctl.Enabled.ToString)
                                .Add.Tag(strXPath & "/valor", ctl.Text)
                            ElseIf TypeOf ctl Is AnguloMaskedTextBox Then
                                .Add.Group(strXPath)
                                .Add.Att(strXPath & "/tipo", "AnguloMaskedTextBox")
                                .Add.Att(strXPath & "/nome", ctl.Name)
                                .Add.Att(strXPath & "/enabled", ctl.Enabled.ToString)
                                .Add.Tag(strXPath & "/valor", ctl.Text)
                            ElseIf TypeOf ctl Is AnguloComboBox Then
                                .Add.Group(strXPath)
                                .Add.Att(strXPath & "/tipo", "TextBox")
                                .Add.Tag(strXPath & "/valor", DirectCast(ctl, AnguloComboBox).SelectedIndex.ToString)
                                'ElseIf TypeOf ctl Is AnguloCheckBox Then
                                '    .Add.Group(strXPath)
                                '    .Add.Att(strXPath & "/tipo", "AnguloCheckBox")
                                '    .Add.Att(strXPath & "/nome", ctl.Name)
                                '    .Add.Att(strXPath & "/enabled", ctl.Enabled.ToString)
                                '    .Add.Tag(strXPath & "/valor", DirectCast(ctl, CheckBox).CheckState.Unchecked.ToString)
                            ElseIf TypeOf ctl Is CheckBox Then
                                .Add.Group(strXPath)
                                .Add.Att(strXPath & "/tipo", "CheckBox")
                                .Add.Att(strXPath & "/nome", ctl.Name)
                                .Add.Att(strXPath & "/enabled", ctl.Enabled.ToString)
                                .Add.Tag(strXPath & "/valor", DirectCast(ctl, CheckBox).CheckState.Unchecked.ToString)
                            ElseIf TypeOf ctl Is AnguloGridView Then
                                '-- não faz nada
                            ElseIf TypeOf ctl Is TextBox Then
                                .Add.Group(strXPath)
                                .Add.Att(strXPath & "/tipo", "TextBox")
                                .Add.Att(strXPath & "/nome", ctl.Name)
                                .Add.Att(strXPath & "/enabled", ctl.Enabled.ToString)
                                .Add.Tag(strXPath & "/valor", ctl.Text)
                            ElseIf ctl.Controls.Count > 0 Then
                                GetControls(ctl)
                            End If
                        Next
                    End With

                Catch ex As Exception
                    Call SendError(ex.Message, ex.StackTrace)
                End Try
            End Sub

            Private Shared Sub SetControl(ByVal controlP As Control, _
                                          ByVal Name As String, _
                                          ByVal Enabled As Boolean, _
                                          ByVal Value As String)
                Try
                    Dim ctl As Control
                    For Each ctl In controlP.Controls
                        If ctl.Name = Name Then
                            If TypeOf ctl Is Label Then
                                ctl.Text = Value
                                If EnabledState_ = True Then ctl.Enabled = Enabled
                            ElseIf TypeOf ctl Is RichTextBox Then
                                DirectCast(ctl, RichTextBox).Text = String.Empty
                            ElseIf TypeOf ctl Is AnguloTextBox Then
                                ctl.Text = Value
                                If EnabledState_ = True Then ctl.Enabled = Enabled
                            ElseIf TypeOf ctl Is AnguloMaskedTextBox Then
                                ctl.Text = Value
                                If EnabledState_ = True Then ctl.Enabled = Enabled
                            ElseIf TypeOf ctl Is AnguloComboBox Then
                                DirectCast(ctl, AnguloComboBox).Buscar = Value
                                If EnabledState_ = True Then ctl.Enabled = Enabled
                                'ElseIf TypeOf ctl Is AnguloCheckBox Then
                                '    DirectCast(ctl, CheckBox).CheckState = IIf(Value = "", CheckState.Checked, CheckState.Unchecked)
                                '    If EnabledState_ = True Then ctl.Enabled = Enabled
                            ElseIf TypeOf ctl Is CheckBox Then
                                DirectCast(ctl, CheckBox).CheckState = IIf(Value = "", CheckState.Checked, CheckState.Unchecked)
                                If EnabledState_ = True Then ctl.Enabled = Enabled
                            ElseIf TypeOf ctl Is AnguloGridView Then
                                '-- não faz nada
                            ElseIf TypeOf ctl Is TextBox Then
                                ctl.Text = Value
                                If EnabledState_ = True Then ctl.Enabled = Enabled
                            End If
                        End If
                        '--
                        If ctl.Controls.Count > 0 Then
                            SetControl(ctl, Name, Enabled, Value)
                        End If
                    Next
                Catch ex As Exception
                    Call SendError(ex.Message, ex.StackTrace)
                End Try
            End Sub
        End Class
    End Class

    ''' <summary>
    ''' Classe para uso de INSERT/UPDATE semelhante aos do RecordSet
    ''' </summary>
    ''' <remarks>Rev. 30/08/2011 11:20</remarks>
    Public Class RecordSet
        Private myConnection As ADODB.Connection
        Private blnInsert, blnCloned As Boolean
        Private intFields As Int16
        Private arrFields As New ArrayList
        '--
        Public QueryString As String
        Public TableName As String
        Public WhereUsed As String
        Public CommandExecuted As String
        Public EOF As Boolean
        Public BOF As Boolean

        ''' <summary>
        ''' Retorna ou insere o valor no campo do recordset
        ''' </summary>
        ''' <param name="FieldName"></param>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Property Field(ByVal FieldName As String) As Object
            Get
                Return GetFieldValue(FieldName)
            End Get
            Set(ByVal value As Object)
                Call SetFieldValue(FieldName, value)
            End Set
        End Property
        ''' <summary>
        ''' Seta o novo valor no recordset
        ''' </summary>
        ''' <param name="FieldName"></param>
        ''' <param name="Value"></param>
        ''' <remarks></remarks>
        Private Sub SetFieldValue(ByVal FieldName As String, ByVal Value As Object)
            Call VerificaExistencia(FieldName)
            Dim intCount As Int16
            Dim myValue As Object = String.Empty
            For intCount = 0 To arrFields.Count - 1
                If arrFields(intCount)(0) = FieldName Then
                    If Not (Value Is DBNull.Value) Then
                        Select Case arrFields(intCount)(2)
                            Case ADODB.DataTypeEnum.adBigInt, ADODB.DataTypeEnum.adInteger, ADODB.DataTypeEnum.adNumeric, ADODB.DataTypeEnum.adSmallInt, ADODB.DataTypeEnum.adTinyInt
                                myValue = CInt(Value)
                            Case ADODB.DataTypeEnum.adCurrency
                                myValue = CSng(Value)
                            Case ADODB.DataTypeEnum.adDecimal
                                myValue = CDec(Value)
                            Case ADODB.DataTypeEnum.adDouble
                                myValue = CDbl(Value)
                            Case ADODB.DataTypeEnum.adDate, ADODB.DataTypeEnum.adDBDate, ADODB.DataTypeEnum.adDBTime, ADODB.DataTypeEnum.adDBTimeStamp
                                myValue = CDate(Value)
                            Case ADODB.DataTypeEnum.adChar, ADODB.DataTypeEnum.adLongVarChar, ADODB.DataTypeEnum.adLongVarWChar, ADODB.DataTypeEnum.adVarChar, ADODB.DataTypeEnum.adVarWChar, ADODB.DataTypeEnum.adWChar
                                myValue = CStr(Value)
                            Case Else
                                myValue = Value
                        End Select
                    Else
                        myValue = Value
                    End If
                    arrFields(intCount)(1) = myValue
                    arrFields(intCount)(3) = True
                    Exit For
                End If
            Next
        End Sub
        ''' <summary>
        ''' Pega o valor do campo do recordset
        ''' </summary>
        ''' <param name="FieldName"></param>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Private Function GetFieldValue(ByVal FieldName As String) As Object
            Call VerificaExistencia(FieldName)
            Dim intCount As Int16
            Dim myValue As Object = DBNull.Value
            For intCount = 0 To arrFields.Count - 1
                If arrFields(intCount)(0) = FieldName Then
                    myValue = arrFields(intCount)(1)
                End If
            Next
            Return myValue
        End Function
        ''' <summary>
        ''' Verifica se existe campo mencionado para insert ou update
        ''' </summary>
        ''' <param name="FieldName"></param>
        ''' <remarks></remarks>
        Private Sub VerificaExistencia(ByVal FieldName As String)
            Dim intCount As Int16
            Dim myValue As Object = DBNull.Value
            For intCount = 0 To arrFields.Count - 1
                If arrFields(intCount)(0) = FieldName Then
                    Exit Sub
                End If
            Next
            Throw New Exception("Campo [" & Me.TableName & "." & FieldName & "] não existe na tabela.")
        End Sub
        ''' <summary>
        ''' Abre a consulta com a base de dados para atualização dos dados
        ''' </summary>
        ''' <param name="Query">Query de consulta</param>
        ''' <param name="Connection">Conexão corrente com a base de dados</param>
        ''' <param name="CursorType">Tipo se cursor</param>
        ''' <param name="LockedType">Tipo de trava</param>
        ''' <remarks></remarks>
        Public Sub Open(ByVal Query As String, _
                        ByVal Connection As ADODB.Connection, _
                        Optional ByRef CursorType As ADODB.CursorTypeEnum = ADODB.CursorTypeEnum.adOpenForwardOnly, _
                        Optional ByVal LockedType As ADODB.LockTypeEnum = ADODB.LockTypeEnum.adLockReadOnly)
            Dim Rs As New ADODB.Recordset
            Try
                Dim intField As Int16
                '--
                myConnection = Connection
                Me.QueryString = Query.Replace("  ", " ")
                '--
                Rs.Open(Me.QueryString, Connection, CursorType, LockedType)
                '---
                Me.EOF = Rs.EOF
                Me.BOF = Rs.BOF
                TableName = GetTableName()
                WhereUsed = GetWhereUsed()
                '--
                For intField = 0 To Rs.Fields.Count - 1
                    Dim Name As String = Rs.Fields(intField).Name                                   '0
                    Dim Value As Object = DBNull.Value                                              '1
                    Dim Type As ADODB.DataTypeEnum = Rs.Fields(intField).Type                       '2
                    Dim ChangedValue As Boolean = False                                             '3
                    Dim PrimaryKey As Boolean = False                                               '4
                    '-- valor
                    If Not Rs.EOF Then
                        Value = Rs.Fields(intField).Value
                    End If
                    '--
                    Dim myArray As Object() = {Name, Value, Type, ChangedValue, PrimaryKey}
                    arrFields.Add(myArray)
                Next
                Rs.Close()
                'Call GetPrimaryKeys()
            Catch ex As Exception
                Call SendError(ex.Message, ex.StackTrace)
            Finally
                Rs = Nothing
            End Try
        End Sub
        ''' <summary>
        ''' Fecha a coexão com o recordset
        ''' </summary>
        ''' <remarks></remarks>
        Public Sub Close()
            myConnection = Nothing
            blnInsert = False
            arrFields.Clear()
            blnCloned = False

            Me.QueryString = Nothing
            Me.TableName = Nothing
            Me.WhereUsed = Nothing
            Me.BOF = Nothing
            Me.EOF = Nothing
        End Sub
        ''' <summary>
        ''' Rertorna a chave primária
        ''' </summary>
        ''' <remarks>Somente para PostgreSQL</remarks>
        Private Sub GetPrimaryKeys()
            Dim Rs As New ADODB.Recordset
            Try
                Dim intCount As Int16
                Dim strSQL As String = "SELECT pg_attribute.attname as column_name, format_type(pg_attribute.atttypid, pg_attribute.atttypmod) " & _
                                       "FROM pg_index, pg_class, pg_attribute " & _
                                       "WHERE pg_class.oid = '" & TableName & "'::regclass " & _
                                       "AND indrelid = pg_class.oid " & _
                                       "AND pg_attribute.attrelid = pg_class.oid " & _
                                       "AND pg_attribute.attnum = any(pg_index.indkey) " & _
                                       "AND indisprimary"
                Rs.Open(strSQL, myConnection, ADODB.CursorTypeEnum.adOpenForwardOnly, ADODB.LockTypeEnum.adLockReadOnly)
                If Not Rs.EOF Then
                    While Not Rs.EOF
                        For intCount = 0 To arrFields.Count - 1
                            If arrFields(intCount)(0) = Rs("column_name").Value Then
                                arrFields(intCount)(4) = True
                            End If
                        Next
                        Rs.MoveNext()
                    End While
                End If
                Rs.Close()
            Catch ex As Exception
                Throw New Exception(ex.Message)
            Finally
                Rs = Nothing
            End Try
        End Sub

        Private Function GetTableName() As String
            Dim myString() As String = Split(Me.QueryString, " ")
            Dim myTableName As String = ""
            Dim intCount As Int16
            For intCount = 0 To myString.Length - 1
                Select Case myString(intCount).ToLower
                    Case "from"
                        myTableName = myString(intCount + 1).ToString
                        Exit For
                End Select
            Next
            Return myTableName
        End Function

        Private Function GetWhereUsed() As String
            Dim blnStart As Boolean
            Dim myString() As String = Split(Me.QueryString, " ")
            Dim myWhere As String = ""
            Dim intCount As Int16
            For intCount = 0 To myString.Length - 1
                If blnStart = True Then
                    myWhere &= " " & myString(intCount)
                End If
                Select Case myString(intCount).ToLower
                    Case "where"
                        blnStart = True
                    Case "order", "limit"
                        Exit For
                End Select
            Next
            Return myWhere
        End Function
        ''' <summary>
        ''' Comando de adição de registro
        ''' </summary>
        ''' <remarks></remarks>
        Public Sub AddNew()
            blnInsert = True
        End Sub
        ''' <summary>
        ''' Comando de atualização de registro
        ''' </summary>
        ''' <remarks></remarks>
        Public Sub Update()
            Try
                Dim mySQL As String = ""
                If blnInsert = True Then
                    mySQL = "INSERT INTO " & TableName & " " & CreateInsertString()
                Else
                    If blnCloned = True Then
                        Throw New Exception("UPDATE não pode ser executado a partir de clone.")
                    End If
                    mySQL = "UPDATE " & TableName & " SET " & CreateUpdateString() & " WHERE " & WhereUsed
                End If
                CommandExecuted = mySQL
                myConnection.Execute(mySQL, ADODB.ExecuteOptionEnum.adExecuteNoRecords)
            Catch ex As Exception
                Throw New Exception(ex.Message & vbCrLf & CommandExecuted)
            End Try
        End Sub

        Private Function CreateInsertString() As String
            Dim strFields As String = "", strValues As String = ""
            Dim intCount As Int16
            For intCount = 0 To arrFields.Count - 1
                If arrFields(intCount)(3) = True Then
                    strFields &= ", " & arrFields(intCount)(0)
                    If Not (arrFields(intCount)(1) Is DBNull.Value) Then
                        Select Case arrFields(intCount)(2)
                            Case ADODB.DataTypeEnum.adBigInt, ADODB.DataTypeEnum.adInteger, ADODB.DataTypeEnum.adNumeric, ADODB.DataTypeEnum.adSmallInt, ADODB.DataTypeEnum.adTinyInt
                                strValues &= ", " & arrFields(intCount)(1).ToString
                            Case ADODB.DataTypeEnum.adCurrency
                                strValues &= ", " & arrFields(intCount)(1).ToString.Replace(",", ".")
                            Case ADODB.DataTypeEnum.adDecimal
                                strValues &= ", " & arrFields(intCount)(1).ToString.Replace(",", ".")
                            Case ADODB.DataTypeEnum.adDouble
                                strValues &= ", " & arrFields(intCount)(1).ToString.Replace(",", ".")
                            Case ADODB.DataTypeEnum.adDate, ADODB.DataTypeEnum.adDBDate
                                strValues &= ", '" & Format(CDate(arrFields(intCount)(1)), "yyyy-MM-dd") & "'"
                            Case ADODB.DataTypeEnum.adDBTime
                                strValues &= ", '" & Format(CDate(arrFields(intCount)(1)), "HH:mm:ss") & "'"
                            Case ADODB.DataTypeEnum.adDBTimeStamp
                                strValues &= ", '" & Format(CDate(arrFields(intCount)(1)), "yyyy-MM-dd HH:mm:ss") & "'"
                            Case ADODB.DataTypeEnum.adChar, ADODB.DataTypeEnum.adLongVarChar, ADODB.DataTypeEnum.adLongVarWChar, ADODB.DataTypeEnum.adVarChar, ADODB.DataTypeEnum.adVarWChar, ADODB.DataTypeEnum.adWChar
                                strValues &= ", '" & arrFields(intCount)(1).ToString.Replace("'", "''") & "'"
                            Case Else
                                strValues &= ", '" & arrFields(intCount)(1).ToString.Replace("'", "''") & "'"
                        End Select
                    Else
                        strValues &= ", null"
                    End If
                End If
            Next
            strFields = "(" & Mid(strFields, 2).Trim & ")"
            strValues = "(" & Mid(strValues, 2).Trim & ")"
            Return strFields & " VALUES " & strValues
        End Function

        Private Function CreateUpdateString() As String
            Dim strFields As String = ""
            Dim intCount As Int16
            For intCount = 0 To arrFields.Count - 1
                If arrFields(intCount)(3) = True Then
                    If Not (arrFields(intCount)(1) Is DBNull.Value) Then
                        Select Case arrFields(intCount)(2)
                            Case ADODB.DataTypeEnum.adBigInt, ADODB.DataTypeEnum.adInteger, ADODB.DataTypeEnum.adNumeric, ADODB.DataTypeEnum.adSmallInt, ADODB.DataTypeEnum.adTinyInt
                                strFields &= ", " & arrFields(intCount)(0) & "=" & arrFields(intCount)(1).ToString
                            Case ADODB.DataTypeEnum.adCurrency
                                strFields &= ", " & arrFields(intCount)(0) & "=" & arrFields(intCount)(1).ToString.Replace(",", ".")
                            Case ADODB.DataTypeEnum.adDecimal
                                strFields &= ", " & arrFields(intCount)(0) & "=" & arrFields(intCount)(1).ToString.Replace(",", ".")
                            Case ADODB.DataTypeEnum.adDouble
                                strFields &= ", " & arrFields(intCount)(0) & "=" & arrFields(intCount)(1).ToString.Replace(",", ".")
                            Case ADODB.DataTypeEnum.adDate, ADODB.DataTypeEnum.adDBDate
                                strFields &= ", " & arrFields(intCount)(0) & "='" & Format(CDate(arrFields(intCount)(1)), "yyyy-MM-dd") & "'"
                            Case ADODB.DataTypeEnum.adDBTime
                                strFields &= ", " & arrFields(intCount)(0) & "='" & Format(CDate(arrFields(intCount)(1)), "HH:mm:ss") & "'"
                            Case ADODB.DataTypeEnum.adDBTimeStamp
                                strFields &= ", " & arrFields(intCount)(0) & "='" & Format(CDate(arrFields(intCount)(1)), "yyyy-MM-dd HH:mm:ss") & "'"
                            Case ADODB.DataTypeEnum.adChar, ADODB.DataTypeEnum.adLongVarChar, ADODB.DataTypeEnum.adLongVarWChar, ADODB.DataTypeEnum.adVarChar, ADODB.DataTypeEnum.adVarWChar, ADODB.DataTypeEnum.adWChar
                                strFields &= ", " & arrFields(intCount)(0) & "='" & arrFields(intCount)(1).ToString.Replace("'", "''") & "'"
                            Case Else
                                strFields &= ", " & arrFields(intCount)(0) & "='" & arrFields(intCount)(1).ToString.Replace("'", "''") & "'"
                        End Select
                    Else
                        strFields &= ", null"
                    End If
                End If
            Next
            strFields = Mid(strFields, 2)
            Return strFields
        End Function

        Private Function CreateWhereClause() As String
            Dim strFields As String = ""
            Dim intCount As Int16
            For intCount = 0 To arrFields.Count - 1
                If arrFields(intCount)(4) = True Then
                    Select Case arrFields(intCount)(2)
                        Case ADODB.DataTypeEnum.adBigInt, ADODB.DataTypeEnum.adInteger, ADODB.DataTypeEnum.adNumeric, ADODB.DataTypeEnum.adSmallInt, ADODB.DataTypeEnum.adTinyInt
                            strFields &= "AND " & arrFields(intCount)(0) & "=" & arrFields(intCount)(1).ToString
                        Case ADODB.DataTypeEnum.adCurrency
                            strFields &= "AND " & arrFields(intCount)(0) & "=" & arrFields(intCount)(1).ToString
                        Case ADODB.DataTypeEnum.adDecimal
                            strFields &= "AND " & arrFields(intCount)(0) & "=" & arrFields(intCount)(1).ToString
                        Case ADODB.DataTypeEnum.adDouble
                            strFields &= "AND " & arrFields(intCount)(0) & "=" & arrFields(intCount)(1).ToString
                        Case ADODB.DataTypeEnum.adDate, ADODB.DataTypeEnum.adDBDate, ADODB.DataTypeEnum.adDBTime, ADODB.DataTypeEnum.adDBTimeStamp
                            strFields &= "AND " & arrFields(intCount)(0) & "='" & arrFields(intCount)(1).ToString & "'"
                        Case ADODB.DataTypeEnum.adChar, ADODB.DataTypeEnum.adLongVarChar, ADODB.DataTypeEnum.adLongVarWChar, ADODB.DataTypeEnum.adVarChar, ADODB.DataTypeEnum.adVarWChar, ADODB.DataTypeEnum.adWChar
                            strFields &= "AND " & arrFields(intCount)(0) & "='" & arrFields(intCount)(1).ToString & "'"
                        Case Else
                            strFields &= "AND " & arrFields(intCount)(0) & "='" & arrFields(intCount)(1).ToString & "'"
                    End Select
                End If
            Next
            strFields = Mid(strFields, 2)
            Return strFields
        End Function
        ''' <summary>
        ''' Define que o RecordSet trabalhará como clonagem
        ''' </summary>
        ''' <remarks></remarks>
        Public Sub Clone()
            Dim intCount As Int16
            For intCount = 0 To arrFields.Count - 1
                arrFields(intCount)(3) = True
            Next

            blnCloned = True
        End Sub
        ''' <summary>
        ''' Ignora campo ao inserir ou atualizar os dados, dando-o como não alterado.
        ''' </summary>
        ''' <param name="FieldName"></param>
        ''' <remarks></remarks>
        Public Sub Supress(ByVal FieldName As String)
            Dim intCount As Int16
            For intCount = 0 To arrFields.Count - 1
                If arrFields(intCount)(0) = FieldName Then
                    arrFields(intCount)(3) = False
                    Exit Sub
                End If
            Next
        End Sub
    End Class


    Public Class XMLSign
        ''' <summary>
        ''' Assina arqvui XML com certificado X509
        ''' </summary>
        ''' <param name="FilePathInput"></param>
        ''' <param name="FilePathOutput"></param>
        ''' <remarks>makecert -r -pe -n "CN=Angulo Inc" -b 01/01/2012 -e 12/31/2016 -sky exchange -ss my c:\temp\testCert.cer</remarks>
        Public Sub AssinarArquivo(ByVal FilePathInput As String, _
                                  ByVal FilePathOutput As String, _
                                  Optional ByVal Elemento As String = "", _
                                  Optional ByVal Atrinuto As String = "")
            ' Leitura do certificado :)
            Dim _xnome As String = "CN=Angulo Inc"
            Dim _X509Cert As New X509Certificate2()
            Dim store As New X509Store("MY", StoreLocation.CurrentUser)
            store.Open(OpenFlags.[ReadOnly] Or OpenFlags.OpenExistingOnly)
            Dim collection As X509Certificate2Collection = DirectCast(store.Certificates, X509Certificate2Collection)
            Dim collection1 As X509Certificate2Collection = DirectCast(collection.Find(X509FindType.FindBySubjectDistinguishedName, _xnome, False), X509Certificate2Collection)
            '--
            _X509Cert = collection1(0)
            ' Leitura de um documento XML    (Test.XML)
            Dim xmlDoc As New XmlDocument()
            xmlDoc.PreserveWhitespace = True
            xmlDoc.Load(FilePathInput)
            ' Ok, vamos assinar o documento
            SignXml(xmlDoc, _X509Cert, Elemento, Atrinuto)
            ' Gravar o documento.
            xmlDoc.Save(FilePathOutput)
        End Sub

        Public Shared Sub SignXml(ByVal Doc As XmlDocument, _
                                  ByVal Key As X509Certificate2, _
                                  ByVal Elemento As String, _
                                  ByVal Atributo As String)
            'não funcional
            If Doc Is Nothing Then
                Throw New ArgumentException("Empty XML Document Object ?")
            End If
            If Key Is Nothing Then
                Throw New ArgumentException("Empty KeyManager Provider ?")
            End If
            Dim signedXml As New SignedXml(Doc)
            ' Passamos a chave :)
            signedXml.SigningKey = Key.PrivateKey
            ' Criamos uma referencia para a assinatura
            Dim reference As New Reference()
            ' pega o uri que deve ser assinada
            Dim _Uri As XmlAttributeCollection = Doc.GetElementsByTagName(Elemento).Item(0).Attributes
            For Each _atributo As XmlAttribute In _Uri
                If _atributo.Name = Atributo Then
                    reference.Uri = _atributo.InnerText
                End If
            Next
            ' Adicionamos uma transformação enveloped à referencia.
            Dim env As New XmlDsigEnvelopedSignatureTransform()
            reference.AddTransform(env)
            '--
            Dim c14 As New XmlDsigC14NTransform()
            reference.AddTransform(c14)
            ' Adicionamos a referência ao objecto SignedXml.
            signedXml.AddReference(reference)
            ' Assinamos.
            signedXml.ComputeSignature()
            ' Extraimos a representação da assinatura em XML
            Dim xmlDigitalSignature As XmlElement = signedXml.GetXml()
            ' Juntamos a assinatura XML ao documento.
            Doc.DocumentElement.AppendChild(Doc.ImportNode(xmlDigitalSignature, True))
            'Et Voilá :)
        End Sub
    End Class

    Public Class XMLRash
        Public Sub AddRash(ByVal xmlPath As String, ByVal Elemento As String)
            Try
                Dim myXML As New XmlDocument()
                Dim myCpt As New ClsCrypto
                Dim xmlContent, rashMD5 As String
                With myXML
                    .Load(xmlPath)
                    If .GetElementsByTagName(Elemento).Count = 0 Then
                        Throw New Exception("Elemento [" & Elemento & "] não encontrado!")
                    End If
                    '-- 
                    xmlContent = .GetElementsByTagName(Elemento).Item(0).InnerXml
                    rashMD5 = myCpt.GeraHashMD5(xmlContent)
                    '-- inserindo o rash
                    Dim newRash As XmlAttribute = .CreateAttribute("rash")
                    newRash.Value = rashMD5
                    .GetElementsByTagName(Elemento).Item(0).Attributes.Append(newRash)
                    '-- salvando
                    .Save(xmlPath)
                End With
            Catch ex As Exception
                Call SendError(ex.Message, ex.StackTrace)
            End Try
        End Sub

        Public Function ValidaRash(ByVal xmlPath As String, ByVal Elemento As String) As Boolean
            Try
                Dim myXML As New XmlDocument()
                Dim myCpt As New ClsCrypto
                Dim xmlContent, rashMD5, rashReal As String
                With myXML
                    .Load(xmlPath)
                    If .GetElementsByTagName(Elemento).Count = 0 Then
                        Throw New Exception("Elemento [" & Elemento & "] não encontrado!")
                    End If
                    '--
                    rashMD5 = .GetElementsByTagName(Elemento).Item(0).Attributes("rash").Value
                    '--
                    xmlContent = .GetElementsByTagName(Elemento).Item(0).InnerXml
                    rashReal = myCpt.GeraHashMD5(xmlContent)
                    '--
                    If rashMD5 <> rashReal Then
                        Exit Try
                    End If
                    Return True
                End With
            Catch ex As Exception
                Call SendError(ex.Message, ex.StackTrace)
            End Try
        End Function
    End Class

End Class
